package com.xyht.sca_s.student_manage_system.modules.carUseManage.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.common.util.TimeUtil;
import com.xyht.sca_s.student_manage_system.modules.asset.util.AssetUtil;
import com.xyht.sca_s.student_manage_system.modules.carUseManage.entity.Resp.SmsCarWarehousingResp;
import com.xyht.sca_s.student_manage_system.modules.carUseManage.entity.SmsCarUseApplication;
import com.xyht.sca_s.student_manage_system.modules.carUseManage.entity.SmsCarWarehousing;
import com.xyht.sca_s.student_manage_system.modules.carUseManage.entity.req.SmsCarWarehousingBartchReq;
import com.xyht.sca_s.student_manage_system.modules.carUseManage.entity.req.SmsCarWarehousingReq;
import com.xyht.sca_s.student_manage_system.modules.carUseManage.mapper.SmsCarUseApplicationMapper;
import com.xyht.sca_s.student_manage_system.modules.carUseManage.mapper.SmsCarWarehousingMapper;
import com.xyht.sca_s.student_manage_system.modules.carUseManage.service.SmsCarWarehousingService;
import com.xyht.sca_s.student_manage_system.modules.common.entity.SmsImportTask;
import com.xyht.sca_s.student_manage_system.modules.common.entity.SmsImportTaskDetail;
import com.xyht.sca_s.student_manage_system.modules.common.mapper.SmsImportTaskDetailMapper;
import com.xyht.sca_s.student_manage_system.modules.common.mapper.SmsImportTaskMapper;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsUserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.carUseManage.constant.carStatusConstant.CAR_STATUS_IN;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskDetailReason.REASON_IMPORT_ERR;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskDetailReason.REASON_INVALID_PARAM;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskNameExample.TASK_NAME_CAR_IMPORT;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskStatus.TASK_STATUS_DONE;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskStatus.TASK_STATUS_ERR;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskTypeConstant.TASK_TYPE_CAR;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2023-07-31
 */
@Service
public class SmsCarWarehousingServiceImpl extends ServiceImpl<SmsCarWarehousingMapper, SmsCarWarehousing> implements SmsCarWarehousingService {
    @Autowired
    SmsCarWarehousingMapper smsCarWarehousingMapper;
    @Autowired
    SmsImportTaskMapper smsImportTaskMapper;
    @Autowired
    AssetUtil assetUtil;
    @Autowired
    SmsImportTaskDetailMapper smsImportTaskDetailMapper;
    @Autowired
    private SmsCarUseApplicationMapper smsCarUseApplicationMapper;
    @Autowired
    private SmsUserMapper smsUserMapper;

    @Transactional
    @Override
    public ResponseResult carAdd(SmsCarWarehousingReq warehousingReq, String userId) {
        if (isNullOrEmpty(warehousingReq.getCarNum()) || isNullOrEmpty(warehousingReq.getCarType())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsCarWarehousing carWarehousing = new SmsCarWarehousing();
        QueryWrapper<SmsCarWarehousing> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SmsCarWarehousing::getCarNum, warehousingReq.getCarNum())
                .or()
                .eq(SmsCarWarehousing::getCarVin, warehousingReq.getCarVin());
        List<SmsCarWarehousing> list = smsCarWarehousingMapper.selectList(queryWrapper);
        if (!isNullOrEmpty(list) && list.size() > 0) {
            return CommonResult.failed(CommonCodeEnum.CAR_USE_INFO_REPEAT);
        }
        BeanUtils.copyProperties(warehousingReq, carWarehousing);
        carWarehousing.setCarWarehousingUserId(userId);
        smsCarWarehousingMapper.insert(carWarehousing);
        return CommonResult.success();
    }

    @Override
    public ResponseResult carDelete(SmsCarWarehousingReq warehousingReq) {
        if (isNullOrEmpty(warehousingReq.getId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsCarWarehousing carWarehousing = smsCarWarehousingMapper.selectById(warehousingReq.getId());
        if (isNullOrEmpty(carWarehousing)) {
            return CommonResult.failed(CommonCodeEnum.DATA_NOT_FOUND);
        }
        smsCarWarehousingMapper.deleteById(warehousingReq.getId());
        return CommonResult.success();
    }

    @Override
    public ResponseResult carUpdate(SmsCarWarehousingReq warehousingReq) {
        if (isNullOrEmpty(warehousingReq.getId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsCarWarehousing warehousing = smsCarWarehousingMapper.selectById(warehousingReq.getId());
        if (isNullOrEmpty(warehousing)) {
            return CommonResult.failed(CommonCodeEnum.DATA_NOT_FOUND);
        }
        SmsCarWarehousing smsCarWarehousing = new SmsCarWarehousing();
        BeanUtils.copyProperties(warehousingReq, smsCarWarehousing);
        smsCarWarehousingMapper.updateById(smsCarWarehousing);
        return CommonResult.success();
    }

    @Override
    public ResponseResult carSelect(String column_name, String search_str, Integer pageSize, Integer pageNum, String bg_date, String end_date) {
        Date bgDate = null;
        Date endDate = null;
        List<SmsCarWarehousing> list11 = new ArrayList<>();
        if (!isNullOrEmpty(bg_date)) {
            bgDate = TimeUtil.StringtoDate(bg_date);
        }
        if (!isNullOrEmpty(end_date)) {
            endDate = TimeUtil.StringtoDate(end_date);

        }
        QueryWrapper<SmsCarWarehousing> queryWrapper = new QueryWrapper<>();
        if (isNullOrEmpty(queryWrapper)) {
            return CommonResult.failed(CommonCodeEnum.DATA_NOT_FOUND);
        }
        if (bgDate != null) {
            queryWrapper.lambda().ge(SmsCarWarehousing::getCreateTime, bgDate);
        }
        if (endDate != null) {
            queryWrapper.lambda().le(SmsCarWarehousing::getCreateTime, endDate);
        }
        if (!isNullOrEmpty(search_str)) {
            queryWrapper.lambda().like(SmsCarWarehousing::getCarName, search_str);
        }
        if (!isNullOrEmpty(column_name)) {
            queryWrapper.lambda().like(SmsCarWarehousing::getCarType, column_name);
        }
        List<SmsCarWarehousing> list1 = smsCarWarehousingMapper.selectList(queryWrapper);
        if (list1.size() == 0) {
            return CommonResult.success(list11, 0);
        }
        queryWrapper.orderByDesc("create_time");
        Page<SmsCarWarehousing> page = new Page<>(pageNum, pageSize);

        smsCarWarehousingMapper.selectPage(page, queryWrapper);
        list11 = page.getRecords();
        int total = (int) page.getTotal();
        return CommonResult.success(list11, total);
    }

    @Override
    public ResponseResult selectById(String id) {
        SmsCarWarehousing query = smsCarWarehousingMapper.selectById(id);
        if (isNullOrEmpty(query)) {
            return CommonResult.failed(CommonCodeEnum.DATA_NOT_FOUND);
        }

        SmsCarWarehousingResp warehousingResp = new SmsCarWarehousingResp();
        BeanUtils.copyProperties(query, warehousingResp);

        //查询借用人信息
        List<SmsCarUseApplication> carUseApplicationList = smsCarUseApplicationMapper.selectList(new LambdaQueryWrapper<SmsCarUseApplication>()
                .eq(SmsCarUseApplication::getCarId, id)
                .eq(SmsCarUseApplication::getIsReturn, 0));
        if (!carUseApplicationList.isEmpty()) {
            SmsUser user = smsUserMapper.selectById(carUseApplicationList.get(0).getApplyUserId());
            if (!isNullOrEmpty(user)) {
                warehousingResp.setBorrowUserId(user.getId());
                warehousingResp.setBorrowUserName(user.getRealName());
                warehousingResp.setBorrowUserPhone(user.getTel());
            }
        }

        return CommonResult.success(warehousingResp);
    }

    @Override
    @Async
    public Future<ResponseResult> batchAddCar(Map<String, Object> map, String userId) {
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(map));
        List<SmsCarWarehousingBartchReq> carList = JSONObject.parseArray(JSON.toJSONString(jsonObject.get("list")), SmsCarWarehousingBartchReq.class);
        if (carList == null || carList.size() < 1) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }
        //创建导入任务
        SmsImportTask smsImportTask = new SmsImportTask();
        smsImportTask.setTaskName(TASK_NAME_CAR_IMPORT);
        smsImportTask.setUserId(userId);
        smsImportTask.setTaskType(TASK_TYPE_CAR);
        smsImportTaskMapper.insert(smsImportTask);

        smsCarWarehousing(carList, smsImportTask.getId(), userId);

        return new AsyncResult<>(CommonResult.success());
    }

    @Override
    public ResponseResult carSelectInHouse(Integer pageSize, Integer pageNum) {
        QueryWrapper<SmsCarWarehousing> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SmsCarWarehousing::getCarStatus, CAR_STATUS_IN);
        queryWrapper.orderByDesc("create_time");
        Page<SmsCarWarehousing> page = new Page<>(pageNum, pageSize);
        smsCarWarehousingMapper.selectPage(page, queryWrapper);
        List<SmsCarWarehousing> list = page.getRecords();
        int total = (int) page.getTotal();
        return CommonResult.success(list, total);
    }

    @Resource
    PlatformTransactionManager transactionManager;

    private void smsCarWarehousing(List<SmsCarWarehousingBartchReq> list, String task_id, String user_id) {
        int OFFSET_ROW = 2;
        Integer task_finish_status = TASK_STATUS_DONE;

        for (int i = 0; i < list.size(); i++) {
            QueryWrapper<SmsCarWarehousing> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SmsCarWarehousing::getCarNum, list.get(i).getCarNum())
                    .or()
                    .eq(SmsCarWarehousing::getCarVin, list.get(i).getCarVin());
            List<SmsCarWarehousing> list1 = smsCarWarehousingMapper.selectList(queryWrapper);
            if (!isNullOrEmpty(list1) && list1.size() > 0) {
                createTeacherImportTaskDetail(task_id, CommonCodeEnum.CAR_USE_INFO_REPEAT.getMsg(), (i + OFFSET_ROW) + "");
                continue;
            }
            //开启事务
            DefaultTransactionDefinition dt = new DefaultTransactionDefinition();
            // 嵌套事务 PROPAGATION_REQUIRES_NEW 每次开启一个新的事务
            dt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            // 设置嵌套事务
            TransactionStatus status = transactionManager.getTransaction(dt);
            SmsCarWarehousingBartchReq storage = list.get(i);
            if (isNullOrEmpty(storage.getCarPower()) || isNullOrEmpty(storage.getCarName())
                    || isNullOrEmpty(storage.getCarNum()) || isNullOrEmpty(storage.getCarVin())
                    || isNullOrEmpty(storage.getCarType())) {
                transactionManager.rollback(status);
                task_finish_status = TASK_STATUS_ERR;
                createTeacherImportTaskDetail(task_id, REASON_INVALID_PARAM, (i + OFFSET_ROW) + "");
                continue;
            }

            try {
                SmsCarWarehousing addWarehousing = new SmsCarWarehousing();
                BeanUtils.copyProperties(storage, addWarehousing);

                addWarehousing.setCarStatus(CAR_STATUS_IN);
                addWarehousing.setCarWarehousingUserId(user_id);
                smsCarWarehousingMapper.insert(addWarehousing);

                transactionManager.commit(status);
            } catch (Exception e) {
                transactionManager.rollback(status);
                task_finish_status = TASK_STATUS_ERR;
                createTeacherImportTaskDetail(task_id, REASON_IMPORT_ERR, (i + OFFSET_ROW) + "");

            }
        }
        SmsImportTask smsImportTask = new SmsImportTask();
        smsImportTask.setId(task_id);
        smsImportTask.setStatus(task_finish_status);
        smsImportTaskMapper.updateById(smsImportTask);
    }

    private void createTeacherImportTaskDetail(String task_id, String reason, String row) {
        SmsImportTaskDetail smsImportTaskDetail = new SmsImportTaskDetail();
        smsImportTaskDetail.setTaskId(task_id);
        smsImportTaskDetail.setFailReason(reason);
        smsImportTaskDetail.setFailRow(row);
        smsImportTaskDetailMapper.insert(smsImportTaskDetail);
    }
}
